﻿using System;
using System.Text;
using UnityWebSocket;

namespace CGF
{
    public class WebSocketClient
    {
        public delegate void DisconnectAction(bool isUnexpected);

        public Action<string, byte[]> onMessage;
        public Action<string> onError;
        public DisconnectAction onClose;
        public bool isConnecting, isConnected;
        private WebSocket socket;
        private bool isUnexpected;

        public async CTask<bool> Connect(string url)
        {
            if (isConnected)
            {
                return true;
            }

            Debug.Log("[WebSocketClient] 连接:" + url);
            CTask<bool> task = CTask<bool>.Create();
            isConnecting = true;
            socket = new WebSocket(url);
            socket.OnOpen += (object sender, OpenEventArgs e) =>
            {
                isConnecting = false;
                isConnected = true;
                isUnexpected = true;
                MainThread.Run(()=>{
                    Debug.Log("[WebSocketClient] 连接成功");
                    task.SetResult(true);
                });
            };
            socket.OnClose += (object sender, CloseEventArgs e) =>
            {
                if (isUnexpected)
                {
                    Debug.LogError("[WebSocketClient] 连接已断开");
                }
                else
                {
                    Debug.Log("[WebSocketClient] 连接已断开");
                }
                isConnected = false;
                isConnecting = false;
                MainThread.Run(() =>
                {
                    onClose?.Invoke(isUnexpected);
                });
            };
            socket.OnMessage += (object sender, MessageEventArgs e) =>
            {
                MainThread.Run(() =>
                {
                    onMessage?.Invoke(e.IsText ? e.Data : null, e.IsBinary ? e.RawData : null);
                });
            };
            socket.OnError += (object sender, UnityWebSocket.ErrorEventArgs e) =>
            {
                MainThread.Run(() =>
                {
                    Debug.LogError($"[WebSocketClient] 连接错误[{url}]：{e.Message}");
                    onError?.Invoke(e.Message);
                });
            };
            socket.ConnectAsync();
            return await task;
        }

        public void Send(string msg)
        {
            socket.SendAsync(Encoding.UTF8.GetBytes(msg));
        }

        public void Send(byte[] data)
        {
            socket.SendAsync(data);
        }

        public void Disconnect()
        {
            isUnexpected = false;
            if (socket != null)
            {
                socket.CloseAsync();
            }
        }

        public void Destroy()
        {
            isUnexpected = false;
            if (socket != null)
            {
                socket.CloseAsync();
            }
        }
    }
}